package top.dingwen.io.treasure.websocket.core;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;
import top.dingwen.io.treasure.websocket.autoconfigure.WebSocketProperties;
import top.dingwen.io.treasure.websocket.constant.WebSocketConstant;
import top.dingwen.io.treasure.websocket.core.holder.WebSocketSessionHolder;
import top.dingwen.io.treasure.websocket.util.WebSocketUtils;

import javax.annotation.Resource;
import java.util.Map;

/**
 * 心跳检测任务
 * @author dingwen
 * @since 2025/04/24
 */
@EnableScheduling
@Component
@Slf4j
public class HeartbeatCheckJob {

    @Resource
    private WebSocketProperties webSocketProperties;

    /**
     * 服务端心跳检测
     */
    @Scheduled(fixedRate = 30000)
    public void serverCheck() {
        WebSocketSessionHolder.getActiveSessions().forEach((sessionKey, lastActiveTime) -> {
            if (System.currentTimeMillis() - lastActiveTime > webSocketProperties.getHeartbeatTimeout()) {
                log.info("{},{},已经超过{}毫秒未活跃,服务端心跳检测未通过已断开", WebSocketConstant.WS_L_O_S,
                        WebSocketConstant.WS_L_HB_CJ,  webSocketProperties.getHeartbeatTimeout());
                WebSocketSessionHolder.removeSession(sessionKey);
            }
        });
    }

    /**
     * 客户端心跳检测
     */
    @Scheduled(fixedRate = 60000)
    public void clientActive() {
        for (Map.Entry<String, WebSocketSession> entry : WebSocketSessionHolder.getSessionsAll().entrySet()) {
            WebSocketSession session = entry.getValue();
            String sessionKey = entry.getKey();
            if (session.isOpen()) {
                log.info("{},{},客户端心跳检测开始,已向客户端发送Ping请求,若客户端回复Pong则进行保活,loginId:{}", WebSocketConstant.WS_L_O_S,
                        WebSocketConstant.WS_L_HB_CJ,sessionKey);
                WebSocketUtils.sendPingMessage(session);
            }else{
                WebSocketSessionHolder.removeSession(sessionKey);
            }
        }
    }
}
